package net.jjjshop.common.service.lbt.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.jjjshop.common.constants.ConfConstants;
import net.jjjshop.common.entity.lbt.LbUserWalletEntity;
import net.jjjshop.common.entity.lbt.UserBillEntityRequest;
import net.jjjshop.common.entity.user.User;
import net.jjjshop.common.entity.user.UserBill;
import net.jjjshop.common.entity.user.UserDedicateRecord;
import net.jjjshop.common.mapper.user.UserBillMapper;
import net.jjjshop.common.service.lbt.LbUserWalletService;
import net.jjjshop.common.service.lbt.UserBillService;
import net.jjjshop.common.service.user.UserService;
import net.jjjshop.common.util.BigDecimalUtil;
import net.jjjshop.framework.shiro.vo.LoginUserRedisVo;
import net.jjjshop.framework.util.LoginUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * UserBillServiceImpl 接口实现
 */
@Service
public class UserBillServiceImpl extends ServiceImpl<UserBillMapper, UserBill> implements UserBillService {

    @Resource
    private UserBillMapper dao;
    @Autowired
    private UserService userService;
    @Resource
    private LbUserWalletService walletService;

    private static final Logger logger = LoggerFactory.getLogger(UserBillServiceImpl.class);

    /**
     * 新增/消耗  总金额
     * @param pm Integer 0 = 支出 1 = 获得
     * @param userId Integer 用户uid
     * @param category String 类型
     * @param date String 时间范围
     * @param type String 小类型
     * @return UserBill
     */
    @Override
    public BigDecimal getSumBigDecimal(Integer pm, Integer userId, String category, String date, String type) {
        QueryWrapper<UserBill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category", category).
                eq("status", 1);
        if (ObjectUtil.isNotNull(userId)) {
            queryWrapper.eq("uid", userId);
        }
        if (null != pm) {
            queryWrapper.eq("pm", pm);
        }
        if (null != type) {
            queryWrapper.eq("type", type);
        }
        List<UserBill> userBills = dao.selectList(queryWrapper);
        if (CollUtil.isEmpty(userBills)) {
            return BigDecimal.ZERO;
        }
        return userBills.stream().map(UserBill::getNumber).reduce(BigDecimal.ZERO, BigDecimal::add).setScale(2, BigDecimal.ROUND_DOWN);
    }





    @Override
    public Boolean addBillRecord(String title, String category, Integer pm, BigDecimal num,Integer uid,  Integer yjType) {
        UserBill bill = new UserBill();
        bill.setPm(pm);
        bill.setAppId(getAppId(uid));
        bill.setTitle(title);
        if (category.equals(ConfConstants.INTEGRAL_DJ)){
            bill.setCategory(ConfConstants.INTEGRAL_TYPE);
        }else{
            bill.setCategory(category);
        }

        bill.setCreateTime(new Date());
        bill.setUid(uid);
        bill.setNumber(num);
        if (null != yjType){
            bill.setType(""+yjType);
        }
        return save(bill);
    }

    @Override
    public Boolean addBillRecord(String title, String category, Integer pm, BigDecimal num,Integer uid,  Integer yjType,Integer orderId) {
        UserBill bill = new UserBill();
        bill.setPm(pm);
        bill.setAppId(getAppId(uid));
        bill.setTitle(title);
        if (category.equals(ConfConstants.INTEGRAL_DJ)){
            bill.setCategory(ConfConstants.INTEGRAL_TYPE);
        }else{
            bill.setCategory(category);
        }

        bill.setCreateTime(new Date());
        bill.setUid(uid);
        bill.setNumber(num);
        bill.setLinkId(orderId+"");
        if (null != yjType){
            bill.setType(""+yjType);
        }
        return save(bill);
    }

    @Override
    public Double getTzTotal() {
        return dao.getTzTotal( LoginUtil.getLoginUserRedisVo().getUserId());
    }

    @Override
    public Integer selectUserHelpNum(Integer uid) {
        return dao.selectUserHelpNum(uid);
    }

    @Override
    public IPage<UserBill> userBillRecord(Integer uid, Integer type, String category, Integer page, Integer limit) {
        Page<UserBill> billPage = new Page<>(page, limit);

        LambdaQueryWrapper<UserBill> lqw = Wrappers.lambdaQuery();
        lqw.select(UserBill::getTitle, UserBill::getNumber, UserBill::getBalance, UserBill::getMark, UserBill::getCreateTime, UserBill::getPm,UserBill::getCategory);
        lqw.eq(UserBill::getUid, uid);
        if (null != type){
            lqw.eq(UserBill::getPm, type);
        }
        if (StringUtils.isNotEmpty(category)){
            lqw.eq(UserBill::getCategory, category);
        }
        lqw.eq(UserBill::getStatus, 1);
        lqw.orderByDesc(UserBill::getId);
        IPage<UserBill> billList = page(billPage,lqw);
        return billList;
    }

    @Override
    public IPage<UserBillEntityRequest> userBillList(UserBillEntityRequest request, Integer page, Integer limit) {
        Page<UserBillEntityRequest> billPage = new Page<>(page, limit);

//        Map<String, Object> map = CollUtil.newHashMap();
//        if (request.getStatus() != null) {
//            map.put("status", request.getStatus());
//        }
//        if (request.getUid() != null) {
//            map.put("uid", request.getUid());
//        }
//        if (request.getPhone() != null) {
//            map.put("phone", request.getPhone());
//        }
//        if (request.getNickname() != null) {
//            map.put("nickname", request.getNickname());
//        }
////        if (request.getRealName() != null) {
////            map.put("real_name", request.getRealName());
////        }
//        if (request.getTitle() != null) {
//            map.put("title", "%"+request.getTitle()+"%");
//        }
//        if (request.getType() != null) {
//            map.put("type", request.getType());
//        }
//        if (request.getPmtype() != null) {
//            map.put("pmtype", request.getPmtype());
//        }

        return dao.userBillList(billPage,request.getStatus(),request.getUid(),request.getPmtype(),request.getPhone(),request.getNickname(),request.getTitle(), request.getType());
    }

    @Override
    public List<UserDedicateRecord> getUserDedicateRecord() {
        return dao.getUserDedicateRecord();
    }

    @Override
    public Boolean saveBill(String title, String category, Integer pm, BigDecimal num, Integer uid, Integer yjType,Integer orderId) {
        logger.info("明细操作-------->",uid+"======"+num.doubleValue());
        UserBill bill = new UserBill();
        bill.setPm(pm);
        bill.setTitle(title);
        bill.setCategory(category);
        bill.setCreateTime(new Date());
        bill.setUid(uid);
        bill.setLinkId(""+orderId);
        bill.setAppId(getAppId(uid));
        if (null != yjType){
            bill.setType(""+yjType);
        }
//

        bill.setNumber(num);
        LbUserWalletEntity walletInfo = walletService.getUserWalletInfo(uid);
        if (null == walletInfo){
            return false;
        }
        if (pm == 1) {
//        LogUtils.getLog().debug("");
            //扣除百分之10到现金账户
            if (category.equals(ConfConstants.COMMISSION_TYPE)) {
                logger.info("明细操作新增佣金-------->",uid+"======"+num.doubleValue());
//                if (walletInfo.getDevote().doubleValue() > 0){
//                    if (walletInfo.getDevote().doubleValue()< num.doubleValue()){
//                        //如果贡献值小于收益值，按照贡献值发放
//                        num = walletInfo.getDevote();
//                    }
                if (title.equals("店铺补贴") || title.equals("消费分红收益")||title.equals("区域服务中心补贴")||title.equals("权益卡兑换")){
                    BigDecimal total = BigDecimalUtil.addDouble(walletInfo.getMoney(), num);
//                    walletInfo.setEntityMoney(BigDecimalUtil.addDouble(walletInfo.getEntityMoney(), a));
                    walletInfo.setTotalMoney(BigDecimalUtil.addDouble(walletInfo.getTotalMoney(), total));
                    walletInfo.setMoney(total);
                }else{
                    if (walletInfo.getDevote().doubleValue()>0){
                        if (walletInfo.getDevote().doubleValue()< num.doubleValue()){
                            BigDecimal a = BigDecimalUtil.subDouble(num,walletInfo.getDevote());
                            addBillRecord("佣金收入冻结",ConfConstants.COMMISSION_DJ_TYPE,1,a,uid,null);
                            walletInfo.setDjMoney(BigDecimalUtil.addDouble(walletInfo.getDjMoney(),a));
                            //如果贡献值小于收益值，按照贡献值发放
                            num = walletInfo.getDevote();
                        }
//                        BigDecimal a = BigDecimalUtil.mul(num, new BigDecimal(0.9));
//                        BigDecimal b = BigDecimalUtil.mul(num, new BigDecimal(0.1));
                        BigDecimal total = BigDecimalUtil.addDouble(walletInfo.getMoney(), num);
//                      walletInfo.setEntityMoney(BigDecimalUtil.addDouble(walletInfo.getEntityMoney(), a));
                        walletInfo.setTotalMoney(BigDecimalUtil.addDouble(walletInfo.getTotalMoney(), num));
//                        walletInfo.setIntegral(BigDecimalUtil.addDouble(walletInfo.getIntegral(), b));
                        walletInfo.setMoney(total);
                        walletInfo.setDevote(BigDecimalUtil.subDouble(walletInfo.getDevote(),num));
                    }else{
                        walletInfo.setDjMoney(BigDecimalUtil.addDouble(walletInfo.getDjMoney(),num));
                        addBillRecord("佣金收入冻结",ConfConstants.COMMISSION_DJ_TYPE,1,num,uid,null);
                    }
                    if (title.equals("财富奖励冻结释放")){
                        walletInfo.setCfMoney(new BigDecimal(0));
                    }

                }

//                    walletInfo.setDevote(BigDecimalUtil.subDouble(walletInfo.getDevote(),num));
//                }else{
//                    logger.info("明细操作 没有贡献值，不能有收益-------->",uid+"======");
//                }
                bill.setNumber(num);

            }else if (category.equals(ConfConstants.INTEGRAL_TYPE)){
                logger.info("明细操作新增积分-------->",uid+"======"+num.doubleValue());
                //增加积分
                walletInfo.setScore(BigDecimalUtil.addDouble(walletInfo.getScore(), num));
            }else if (category.equals(ConfConstants.INTEGRAL_DJ)){
                logger.info("明细操作新增积分-------->",uid+"======"+num.doubleValue());
                //增加积分
                walletInfo.setScoreFreeze(BigDecimalUtil.addDouble(walletInfo.getScoreFreeze(), num));
            }else if (category.equals(ConfConstants.WEALTH_DJ_TYPE)){
                logger.info("冻结财富奖励-------->",uid+"======"+num.doubleValue());
                //增加积分
                walletInfo.setCfMoney(BigDecimalUtil.addDouble(walletInfo.getCfMoney(), num));
            }
            if (!walletService.updateById(walletInfo)){
                return false;
            }
        }
        //支出
        if (pm == 0) {
            if (category.equals(ConfConstants.COMMISSION_TYPE)) {
                walletInfo.setMoney(BigDecimalUtil.subDouble(walletInfo.getMoney(), num));
            }
            if (category.equals(ConfConstants.COMMISSION_WJJ)) {
                walletInfo.setIntegral(BigDecimalUtil.subDouble(walletInfo.getIntegral(), num));
            }
            if (!walletService.updateById(walletInfo)){
                return false;
            }
        }
        if (category.equals(ConfConstants.COMMISSION_TYPE)) {
            User byId = userService.getById(walletInfo.getUid());
            byId.setBalance(walletInfo.getMoney());
            userService.updateById(byId);
        }
        return save(bill);
    }



    @Override
    public Boolean saveBill(String title, String category, Integer pm, BigDecimal num, Integer uid, Integer yjType,String mark,Integer orderId) {
        logger.info("扶持记录保存-------->",uid+"======"+num.doubleValue());
        UserBill bill = new UserBill();
        bill.setPm(pm);
        bill.setTitle(title);
        bill.setCategory(category);
        bill.setAppId(getAppId(uid));
        bill.setCreateTime(new Date());
        bill.setUid(uid);
        bill.setLinkId(""+orderId);
        bill.setMark(mark);//这里标记是用户的扶持记录
        if (null != yjType){
            bill.setType(""+yjType);
        }

        bill.setNumber(num);
//        bill.setNumber(num);
        LbUserWalletEntity walletInfo = walletService.getUserWalletInfo(uid);
        if (pm == 1) {
//        LogUtils.getLog().debug("");
            //扣除百分之10到现金账户
            if (category.equals(ConfConstants.COMMISSION_TYPE)) {
                logger.info("明细操作新增佣金-------->",uid+"======"+num.doubleValue());
                if (walletInfo.getDevote().doubleValue() > 0){
                    if (walletInfo.getDevote().doubleValue()< num.doubleValue()){
                        //如果贡献值小于收益值，按照贡献值发放
                        num = walletInfo.getDevote();
                    }
//                    BigDecimal a = BigDecimalUtil.mul(num, new BigDecimal(ConfConstants.HANG_SALE_FEES));
                    BigDecimal total = BigDecimalUtil.addDouble(walletInfo.getMoney(),num);
//                    walletInfo.setEntityMoney(BigDecimalUtil.addDouble(walletInfo.getEntityMoney(), a));
                    walletInfo.setTotalMoney(BigDecimalUtil.addDouble(walletInfo.getTotalMoney(), num));
                    walletInfo.setMoney(total);
//                    walletInfo.setDevote(BigDecimalUtil.subDouble(walletInfo.getDevote(),num));
                }else{
                    logger.info("明细操作 没有贡献值，不能有收益-------->",uid+"======");
                }

            }
            if (!walletService.updateById(walletInfo)){
                return false;
            }
        }
        //支出
        if (pm == 0) {
            if (category.equals(ConfConstants.COMMISSION_TYPE)) {
                walletInfo.setMoney(BigDecimalUtil.subDouble(walletInfo.getMoney(), num));
            }
            if (!walletService.updateById(walletInfo)){
                return false;
            }

        }
        User byId = userService.getById(walletInfo.getUid());
        byId.setBalance(walletInfo.getMoney());
        userService.updateById(byId);
        return save(bill);
    }


    private Integer getAppId(Integer uid){
      return   10001;
    }
}

